package com.mindskip.xzs.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mindskip.xzs.context.WebContext;
import com.mindskip.xzs.domain.dto.admin.exampaper.ExamPaperDTO;
import com.mindskip.xzs.domain.dto.admin.task.TaskItemObject;
import com.mindskip.xzs.domain.dto.admin.task.TaskPageDTO;
import com.mindskip.xzs.domain.dto.admin.task.TaskWithExamPaperDTO;
import com.mindskip.xzs.domain.entity.ExamPaper;
import com.mindskip.xzs.domain.entity.TaskExam;
import com.mindskip.xzs.domain.entity.TextContent;
import com.mindskip.xzs.domain.vo.admin.exampaper.ExamPaperVO;
import com.mindskip.xzs.domain.vo.admin.task.TaskWithExamPaperVO;
import com.mindskip.xzs.domain.vo.admin.task.TaskVO;
import com.mindskip.xzs.repository.BaseMapper;
import com.mindskip.xzs.repository.ExamPaperMapper;
import com.mindskip.xzs.repository.TaskExamMapper;
import com.mindskip.xzs.repository.TextContentMapper;
import com.mindskip.xzs.service.TaskExamService;
import com.mindskip.xzs.utility.BeanCopyUtils;
import com.mindskip.xzs.utility.DateTimeUtil;
import com.mindskip.xzs.utility.JsonUtil;
import com.mindskip.xzs.utility.PageInfoUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class TaskExamServiceImpl extends BaseServiceImpl<TaskExam> implements TaskExamService {

    private final TaskExamMapper taskExamMapper;

    private final TextContentMapper textContentMapper;

    private final ExamPaperMapper examPaperMapper;

    private final WebContext webContext;

    public TaskExamServiceImpl(BaseMapper<TaskExam> baseMapper, TaskExamMapper taskExamMapper, TextContentMapper textContentMapper, ExamPaperMapper examPaperMapper, WebContext webContext) {
        super(baseMapper);
        this.taskExamMapper = taskExamMapper;
        this.textContentMapper = textContentMapper;
        this.examPaperMapper = examPaperMapper;
        this.webContext = webContext;
    }

    @Override
    public PageInfo<TaskVO> getTaskExamByPage(TaskPageDTO taskPageDTO) {

        PageHelper.startPage(taskPageDTO.getPageIndex(), taskPageDTO.getPageSize(), "id desc");
        List<TaskExam> taskExamList = taskExamMapper.selectByPage(taskPageDTO);
        PageInfo<TaskExam> oldPageInfo = new PageInfo<>(taskExamList);

        List<TaskVO> taskVOList = taskExamList
                .stream()
                .map(new Function<TaskExam, TaskVO>() {
                    @Override
                    public TaskVO apply(TaskExam taskExam) {

                        TaskVO taskVO = BeanCopyUtils.copyBean(taskExam, TaskVO.class);
                        taskVO.setCreateTime(DateTimeUtil.dateFormat(taskExam.getCreateTime()));
                        return taskVO;
                    }
                })
                .collect(Collectors.toList());

        return PageInfoUtil.copyMap(oldPageInfo, taskVOList);
    }

    @Override
    public TaskWithExamPaperVO getTaskWithExamPaperVO(Integer id) {

        TaskExam taskExam = taskExamMapper.selectByPrimaryKey(id);

        if (ObjectUtils.isEmpty(taskExam)) {
            throw new RuntimeException("任务的id非法");
        }

        // 将 TaskExam 转换为 TaskWithExamPaperVO
        return taskExamToTaskWithExamPaperVO(taskExam);
    }

    // 将 TaskExam 转换为 TaskWithExamPaperVO
    public TaskWithExamPaperVO taskExamToTaskWithExamPaperVO(TaskExam taskExam) {

        // 给 TaskWithExamPaperVO 的 id、gradeLevel、title 属性赋值
        TaskWithExamPaperVO taskWithExamPaperVO = BeanCopyUtils.copyBean(taskExam, TaskWithExamPaperVO.class);

        TextContent textContent = textContentMapper.selectByPrimaryKey(taskExam.getFrameTextContentId());

        List<TaskItemObject> taskItemObjectList = JsonUtil.toJsonListObject(textContent.getContent(), TaskItemObject.class);

        if (ObjectUtils.isEmpty(taskItemObjectList)) {
            throw new RuntimeException("查询任务所对应的文本内容失败");
        }

        // 将 List<TaskItemObject> 转换为 List<ExamPaperVO>
        List<ExamPaperVO> examPaperVOList = taskItemObjectList
                .stream()
                .map(taskItemObject -> {
                    ExamPaper examPaper = examPaperMapper.selectByPrimaryKey(taskItemObject.getExamPaperId());
                    ExamPaperVO examPaperVO = BeanCopyUtils.copyBean(examPaper, ExamPaperVO.class);
                    // BeanUtils 无法将 Date 类型的属性转换为 String 类型，所以需要手动转换
                    examPaperVO.setCreateTime(DateTimeUtil.dateFormat(examPaper.getCreateTime()));
                    return examPaperVO;
                })
                .collect(Collectors.toList());

        // 给 TaskWithExamPaperVO 的 paperItems 属性赋值
        taskWithExamPaperVO.setPaperItems(examPaperVOList);

        return taskWithExamPaperVO;
    }

    @Override
    @Transactional
    public void insertOrUpdate(TaskWithExamPaperDTO taskWithExamPaperDTO) {

        if (taskWithExamPaperDTO.getId() == null) {
            insert(taskWithExamPaperDTO, webContext.getCurrentUser().getId(), webContext.getCurrentUser().getUserName());
        }else {
            update(taskWithExamPaperDTO);
        }

    }

    public void insert(TaskWithExamPaperDTO taskWithExamPaperDTO, Integer userId, String userName) {

        // 给 taskExam 的 id(插入时id为null)、title、gradeLevel 属性赋值
        TaskExam taskExam = BeanCopyUtils.copyBean(taskWithExamPaperDTO, TaskExam.class);

        TextContent textContent = new TextContent();
        // 将 TaskWithExamPaperDTO 中的 paperItems 属性转换为 JSON 字符串
        List<ExamPaperDTO> paperItems = taskWithExamPaperDTO.getPaperItems();
        String content = setTaskTextContent(paperItems);
        // 给 textContent 中的 content 赋值
        textContent.setContent(content);

        Date now = new Date();

        // 给 textContent 中的 createTime 赋值
        textContent.setCreateTime(now);

        int i = textContentMapper.insertSelective(textContent);
        if (i <= 0) {
            throw new RuntimeException("插入任务所对应的文本内容失败");
        }

        // 给 taskExam 的 frameTextContentId 属性赋值
        taskExam.setFrameTextContentId(textContent.getId());

        // 给 taskExam 的 createUser 属性赋值
        taskExam.setCreateUser(userId);

        // 给 taskExam 的 createTime 属性赋值
        taskExam.setCreateTime(now);

        // 给 taskExam 的 deleted 属性赋值
        taskExam.setDeleted(false);

        // 给 taskExam 的 createUserName 属性赋值
        taskExam.setCreateUserName(userName);

        int i1 = taskExamMapper.insertSelective(taskExam);
        if (i1 <= 0) {
            throw new RuntimeException("插入任务失败");
        }

        //更新试卷的taskId
        List<Integer> paperIds = taskWithExamPaperDTO.getPaperItems()
                .stream()
                .map(ExamPaperDTO::getId)
                .collect(Collectors.toList());
        examPaperMapper.updateTaskPaper(taskExam.getId(), paperIds);
        taskWithExamPaperDTO.setId(taskExam.getId());
    }

    public String setTaskTextContent(List<ExamPaperDTO> paperItems) {

        List<TaskItemObject> taskItemObjectList = paperItems
                .stream()
                .map(new Function<ExamPaperDTO, TaskItemObject>() {
                    @Override
                    public TaskItemObject apply(ExamPaperDTO examPaperDTO) {
                        TaskItemObject taskItemObject = new TaskItemObject();
                        taskItemObject.setExamPaperId(examPaperDTO.getId());
                        taskItemObject.setExamPaperName(examPaperDTO.getName());
                        return taskItemObject;
                    }
                })
                .collect(Collectors.toList());

        return JsonUtil.toJsonStr(taskItemObjectList);
    }

    public void update(TaskWithExamPaperDTO taskWithExamPaperDTO) {

        TaskExam taskExam = taskExamMapper.selectByPrimaryKey(taskWithExamPaperDTO.getId());

        BeanUtils.copyProperties(taskWithExamPaperDTO, taskExam);

        TextContent textContent = textContentMapper.selectByPrimaryKey(taskExam.getFrameTextContentId());

        List<TaskItemObject> taskItemObjectList = JsonUtil.toJsonListObject(textContent.getContent(), TaskItemObject.class);
        if (ObjectUtils.isEmpty(taskItemObjectList)) {
            throw new RuntimeException("查询任务所对应的文本内容失败");
        }
        //清空试卷任务的试卷Id，后面会统一设置
        List<Integer> oldPaperIds = taskItemObjectList
                .stream()
                .map(TaskItemObject::getExamPaperId)
                .collect(Collectors.toList());
        examPaperMapper.clearTaskPaper(oldPaperIds);

        // 将 TaskWithExamPaperDTO 中的 paperItems 属性转换为 JSON 字符串
        List<ExamPaperDTO> paperItems = taskWithExamPaperDTO.getPaperItems();
        String content = setTaskTextContent(paperItems);
        textContent.setContent(content);

        int i = textContentMapper.updateByPrimaryKeySelective(textContent);
        if (i <= 0) {
            throw new RuntimeException("更新任务所对应的文本内容失败");
        }

        int i1 = taskExamMapper.updateByPrimaryKeySelective(taskExam);
        if (i1 <= 0) {
            throw new RuntimeException("更新任务失败");
        }

        //更新试卷的taskId
        List<Integer> paperIds = taskWithExamPaperDTO.getPaperItems()
                .stream()
                .map(ExamPaperDTO::getId)
                .collect(Collectors.toList());
        examPaperMapper.updateTaskPaper(taskExam.getId(), paperIds);
        taskWithExamPaperDTO.setId(taskExam.getId());
    }

    @Override
    public void softDelete(Integer id) {

        TaskExam taskExam = taskExamMapper.selectByPrimaryKey(id);

        taskExam.setDeleted(true);

        int i = taskExamMapper.updateByPrimaryKeySelective(taskExam);
        if (i <= 0) {
            throw new RuntimeException("软删除任务失败");
        }
    }

    @Override
    public List<TaskExam> getTaskExamByGradeLevel(Integer gradeLevel) {

        return taskExamMapper.selectByGradeLevel(gradeLevel);
    }
}
